using System;
using System.IO;
using System.Collections;
using System.Web.Mail;
using System.Diagnostics;

namespace Copperline.Escriba
{
	/// <summary>
	/// Sends log events as an email message
	/// </summary>
	public class MailLogger : LoggerBase
	{
		public MailLogger()
		{
			Init( null, null, null, ESeverity.debug, ETrigger.threshold );
		}

		/// <summary>
		/// Creates an instance of the <c>MailLogger</c> class
		/// </summary>
		/// <param name="sFrom">the "From" header for all mail messages sent by this logger</param>
		/// <param name="sTo">the "To" header for all mail messages sent by this logger</param>
		/// <param name="sSubject">the "Subject" header used by all mail messages</param>
		public MailLogger( string sFrom, string sTo, string sSubject )
		{
			Init( sFrom, sTo, sSubject, ESeverity.debug, ETrigger.threshold );
		}

		/// <summary>
		/// Creates an instance of the <c>MailLogger</c> class
		/// </summary>
		/// <param name="sFrom">the "From" header for all mail messages sent by this logger</param>
		/// <param name="sTo">the "To" header for all mail messages sent by this logger</param>
		/// <param name="sSubject">the "Subject" header used by all message sent by this logger</param>
		/// <param name="severity">the minimum (or threshold) severity for sending mail</param>
		/// <param name="trigger">the type of trigger to apply in checking the severities of
		/// <c>LogEntry</c> objects received for logging</param>
		public MailLogger( string sFrom, string sTo, string sSubject, ESeverity severity, ETrigger trigger )
		{
			Init( sFrom, sTo, sSubject, severity, trigger );
		}

		private void Init( string sFrom, string sTo, string sSubject, ESeverity severity, ETrigger trigger )
		{
			Enabled = true;
			MailFrom = sFrom;
			MailTo = sTo;
			MailSubject = sSubject;
			Filter = new SeverityFilter( severity, trigger );

			TextFormatter formatter = new TextFormatter();
			formatter.AlignMultiple = false;
			formatter.FieldSeparator = "  ";

			Type type = Type.GetType("Copperline.Escriba.LogEntry");
			formatter.SetFieldSequence(
				new FieldFormatter( type.GetProperty("Severity"), LogEntry.SeverityFormat ),
				new FieldFormatter( type.GetProperty("TimeStamp"), LogEntry.TimeStampFormat ));

			Formatter = formatter;
		}

		private string sTo;
		/// <summary>
		/// The recipient's address
		/// </summary>
		public string MailTo
		{
			get { return sTo; }
			set { sTo = value; }
		}

		private string sFrom;
		/// <summary>
		/// The sender's address.
		/// </summary>
		public string MailFrom
		{
			get { return sFrom; }
			set { sFrom = value; }
		}

		private string sSubject;
		/// <summary>
		/// The subject line
		/// </summary>
		public string MailSubject
		{
			get { return sSubject; }
			set { sSubject = value; }
		}

		/// <summary>
		/// Sends a log entry as an email
		/// </summary>
		/// <param name="logEntry"></param>
		public override void Write( LogEntry logEntry )
		{
			StringWriter sw = new StringWriter();
			Append( sw, logEntry );
			sw.Close();
			Send( MailSubject, sw.GetStringBuilder().ToString().Trim() );
		}

		/// <summary>
		/// Sends the mail
		/// </summary>
		/// <param name="sSubject">the subject line of the mail message</param>
		/// <param name="sBody">the body of the mail message</param>
		protected internal void Send( string sSubject, string sBody )
		{
			try
			{
				if( sBody != null && sBody.Length > 0 )
					SmtpMail.Send( MailFrom, MailTo, sSubject, sBody );
			}
			catch( Exception ex )
			{
				Fault = true;
				LastError = new EscribaException("Error sending mail", ex );
			}
		}
	}
}
